/*!
\file AlgorithmVisualizer.cpp
\brief Contains implementation of AlgorithmVisualizer.
\ingroup GUI
*/

#include"AlgorithmVisualizer.h"

AlgorithmVisualizer::AlgorithmVisualizer( Algorithm *a, QWidget *parent ):QWidget( parent ){
	m_algorithm = a;
	m_timer = 0;
	
	m_layout = new QHBoxLayout(this);
	setLayout( m_layout );
	
	m_graphVisualizer = new GraphVisualizer( new DManager(a->graph()->toDOT()), this );
	m_layout->addWidget( m_graphVisualizer );
	connect( m_graphVisualizer, SIGNAL(requestUpdate()), this, SLOT(_requestUpdate()) );
	connect( m_graphVisualizer, SIGNAL(requestPlay()), this, SLOT(_requestPlay()) );
	connect( m_graphVisualizer, SIGNAL(requestStop()), this, SLOT(_requestStopTimedUpdate()) );
	
	m_childWidget = new QWidget(this);
	m_layout->addWidget( m_childWidget );
	
	m_childLayout = new QVBoxLayout(m_childWidget);
	m_childWidget->setLayout(m_childLayout);
	
	m_accessWidget = new GraphAccessWidget(m_childWidget);
	m_childLayout->addWidget(m_accessWidget);
	
	m_logArea = new AlgorithmLogArea(m_childWidget);
	m_childLayout->addWidget(m_logArea);
}

AlgorithmVisualizer::~AlgorithmVisualizer(){

}

void AlgorithmVisualizer::_requestUpdate(){
	bool shouldRepeat = false;
	do{
		Action *a = m_algorithm->_popAction();
		if( a == 0 ){
			QMessageBox::information( this, "Visualization completed", "Visualization for given Algorithm is completed." );
			return;
		}
		shouldRepeat = a->isUninteresting();
		m_graphVisualizer->update(a);
		delete a;
	}while( shouldRepeat );
}

void AlgorithmVisualizer::_requestTimedUpdate(){
	bool shouldRepeat = false;
	do{
		Action *a = m_algorithm->_popAction();
		if( a == 0 ){
			QMessageBox::information( this, "Visualization completed", "Visualization for given Algorithm is completed." );
			m_timer->stop();
			m_timer->disconnect();
			delete m_timer;
			m_timer = 0;
			return;
		}
		shouldRepeat = a->isUninteresting();
		m_graphVisualizer->update(a);
		delete a;
	}while( shouldRepeat );
}

void AlgorithmVisualizer::_requestStopTimedUpdate(){
	if( m_timer == 0 )
		return;
	m_timer->stop();
	m_timer->disconnect();
	delete m_timer;
	m_timer = 0;
}

void AlgorithmVisualizer::_requestPlay(){
	if( m_timer != 0 )
		return;
	
	m_timer = new QTimer(this);
	connect( m_timer, SIGNAL(timeout()), this, SLOT(_requestTimedUpdate()) );
	m_timer->start(1000);
}

void AlgorithmVisualizer::_accessNode(int /*id*/){
	m_accessWidget->node();
}

void AlgorithmVisualizer::_accessEdge(int /*id*/){
	m_accessWidget->edge();
}

void AlgorithmVisualizer::_addContainer(int id){
	ContainerVisualizer *vis = new ContainerVisualizer( id, m_childWidget );
	m_childLayout->addWidget(vis);
	m_containers.push_back(vis);
}

void AlgorithmVisualizer::_removeContainer( int id ){
	printf("AlgorithmVisualizer::_removeContainer called.\n");
	m_childLayout->removeWidget(_container(id));
	_container(id)->hide();
	for( int i = 0; i < m_containers.size(); i++ ){
		if( m_containers[i]->identifier() == id ){
			delete m_containers.takeAt(i);
			break;
		}
	}
}

ContainerVisualizer *AlgorithmVisualizer::_container( int i ){
	printf("AlgorithmVisualizer::_container called.\n");
	for( int j = 0; j < m_containers.size(); j++ )
		if( m_containers[j]->identifier() == i )
			return m_containers[j];
	_addContainer( i );
	return _container( i );
}

void AlgorithmVisualizer::_containerNewElement( int container, int i ){
	_container( container )->insert( i );
}

void AlgorithmVisualizer::_containerRemoveElement( int container, int i ){
	_container( container )->remove( i );
}

void AlgorithmVisualizer::_containerSetNode( int container, int i, int nodeID, QString label ){
	_container( container )->setNode( i, nodeID, label );
}

void AlgorithmVisualizer::_containerSetEdge( int container, int i, int from, int to, QString label ){
	_container( container )->setEdge( i, from, to, label );
}

void AlgorithmVisualizer::_containerSetData( int container, int i, QString data ){
	_container( container )->setData( i, data );
}

void AlgorithmVisualizer::_logComment( QString comment ){
	m_logArea->log(comment);
}

